package cc.iotkit.manager.task;

import cc.iotkit.common.thing.ThingModelMessage;
import cc.iotkit.data.manager.IAlertFenceData;
import cc.iotkit.data.manager.IDeviceDailyReportData;
import cc.iotkit.data.manager.IDeviceInfoData;
import cc.iotkit.data.manager.IMapFenceDevicesData;
import cc.iotkit.manager.service.IMapService;
import cc.iotkit.model.alert.AlertFence;
import cc.iotkit.model.device.DeviceDailyReport;
import cc.iotkit.model.device.DeviceInfo;
import cc.iotkit.model.map.MapFenceDevices;
import cc.iotkit.temporal.IThingModelMessageData;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.xxl.job.core.context.XxlJobHelper;
import com.xxl.job.core.handler.annotation.XxlJob;
import org.apache.commons.lang3.ObjectUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZoneOffset;
import java.util.*;
import java.util.stream.Collectors;

/***
 * 分析是否超出围栏
 */
@Component
public class AnalysisFence {
    @Autowired
    private IThingModelMessageData thingModelMessageData;

    @Autowired
    private IAlertFenceData alertFenceData;
    @Autowired
    private IMapFenceDevicesData mapFenceDevicesData;
    @Autowired
    private IDeviceInfoData deviceInfoData;
    @Autowired
    private IMapService mapService;
    @Autowired
    private StringRedisTemplate redisTemplate;

    private String LastTimeCacheKey="sync:analysis_fence_status";
    private static Logger logger = LoggerFactory.getLogger(AnalysisFence.class);

    @XxlJob("AnalysisFenceStatus")
    public void run() throws Exception {
        logger.info("xxl-job:running AnalysisFenceStatus...");
        try {
            String startTime=getLastTime();
            String endTime=LocalDateTime.now().toString();
            List<ThingModelMessage> messageList = thingModelMessageData.findLastLocationReports(startTime, endTime);
            List<AlertFence> reports = new ArrayList<>();
            //遍历等检测设备
            messageList.forEach(m -> {
                //属性转换
                /*DeviceDailyReport r = JSONUtil.toBean(StrUtil.toCamelCase(m.getData().toString()), DeviceDailyReport.class);
                if(r.getLocations()==null) return;*/

                //获取设备绑定的围栏
                MapFenceDevices mapFenceDevices=new MapFenceDevices();
                mapFenceDevices.setDeviceId(m.getDeviceId());
                List<MapFenceDevices> fenceDevices= mapFenceDevicesData.findAllByCondition(mapFenceDevices);
                if(fenceDevices.size()==0) return;

                //获取设备信息
                DeviceInfo deviceInfo= deviceInfoData.findById(m.getDeviceId());
                String locationsStr="";
                //获取最后一次定位信息
                Map<String, Object> data=  mapService.getLatestPoint(deviceInfo.getAmapTid(),deviceInfo.getAmapTrid());
                if(data!=null) {
                    locationsStr = data.get("location").toString();
                    Long locatetime=Long.valueOf(data.get("locatetime").toString());
                    Long time=LocalDateTime.now().minusMinutes(5).atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
                    //判断是否在5分钟内
                    if(time>locatetime) return;
                }else{
                    return;
                }

                /*if(deviceInfo.getLocate()==null||deviceInfo.getLocate().getLatitude()==null) return;
                String locationsStr= deviceInfo.getLocate().getLongitude()+","+deviceInfo.getLocate().getLatitude();*/

                //判断是否超出围栏
                String gfids=fenceDevices.stream().map(map->map.getGfid().toString()).collect(Collectors.joining(","));
                List<Map<String,Object>> results= mapService.findFenceStatus(locationsStr,gfids);
                if(results!=null) {
                    String finalLocationsStr = locationsStr;
                    results.forEach(res -> {
                        //超出范围
                        if (res.get("in").toString().equals("0")) {
                            AlertFence row = new AlertFence();
                            row.setCreateAt(LocalDateTime.now());
                            row.setLocation(finalLocationsStr);
                            row.setDeviceId(m.getDeviceId());
                            row.setGfid(Integer.valueOf(res.get("gfid").toString()));
                            row.setGfname(res.get("gfname").toString());
                            row.setTenantId(deviceInfo.getTenantId());
                            reports.add(row);
                        }
                    });
                }
            });

            alertFenceData.batchSave(reports);
            this.setLastTime(endTime);
            logger.info("xxl-job:running AnalysisFenceStatus finished");
        }
        catch (Exception e){
            logger.info("xxl-job-error:"+e.getMessage());
            XxlJobHelper.log(e);
            XxlJobHelper.handleFail();
        }
        /*XxlJobHelper.log("XXL-JOB, Hello World.");

        for (int i = 0; i < 5; i++) {
            XxlJobHelper.log("beat at:" + i);
            TimeUnit.SECONDS.sleep(2);
        }*/
    }

    public String getLastTime() {
        Object last = redisTemplate.opsForValue().get(LastTimeCacheKey);
        if(ObjectUtils.isEmpty(last)){
            Calendar c = Calendar.getInstance();
            return LocalDateTime.of(c.get(Calendar.YEAR),c.get(Calendar.MONTH),c.get(Calendar.DAY_OF_MONTH),0,0,0,1).toString();
        }
        return last.toString();
    }

    public void setLastTime(String lastTime) {
        redisTemplate.opsForValue().set(LastTimeCacheKey, lastTime);
    }
}
